<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>星星向你眨眼睛</title>
  <link rel="icon" href="https://img.kaikeba.com/kkb_portal_icon.ico">
  <style>
    body {
      margin: 0;
      overflow: hidden;
    }

    #canvas {
      background: url("./images/sky.jpg");
      background-size: cover;
      background-position: right bottom;
    }

    #audio {
      position: absolute;
      right: 20px;
      bottom: 20px;
      opacity: 10%;
      transition: opacity 200ms;
      z-index: 20;
    }

    #audio:hover {
      opacity: 90%;
    }
  </style>
</head>

<body>
  <canvas id="canvas"></canvas>
  <audio id="audio" controls loop autoplay>
    <source src="./audio/cef.mp3" type="audio/mpeg" />
  </audio>
  <!-- 顶点着色器 -->
  <script id="vertexShader" type="x-shader/x-vertex">
      attribute vec4 a_Position;
      attribute float a_PointSize;
      void main(){
          //点位
          gl_Position=a_Position;
          //尺寸
          gl_PointSize=a_PointSize;
      }
    </script>
  <!-- 片元着色器 -->
  <script id="fragmentShader" type="x-shader/x-fragment">
      precision mediump float;
      uniform vec4 u_FragColor;
      void main(){
        float dist=distance(gl_PointCoord,vec2(0.5,0.5));
        if(dist<0.5){
          gl_FragColor=u_FragColor;
        }else{
          discard;
        }
      }
    </script>
  <script type="module">
    import { initShaders } from "../jsm/Utils.js";
    import Compose from "../jsm/Compose.js";
    import Track from "../jsm/Track.js";

    const canvas = document.querySelector("#canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // 获取着色器文本
    const vsSource = document.querySelector("#vertexShader").innerText;
    const fsSource = document.querySelector("#fragmentShader").innerText;

    //三维画笔
    const gl = canvas.getContext("webgl");
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

    //初始化着色器
    initShaders(gl, vsSource, fsSource);

    //设置attribute 变量
    // a_Position=vec4(1,0,0,1)
    const a_Position = gl.getAttribLocation(gl.program, "a_Position");
    const a_PointSize = gl.getAttribLocation(gl.program, "a_PointSize");
    const u_FragColor = gl.getUniformLocation(gl.program, "u_FragColor");

    const stars = [];

    //合成对象
    const compose = new Compose();

    //声明颜色 rgba
    gl.clearColor(0, 0, 0, 0);
    //刷底色
    gl.clear(gl.COLOR_BUFFER_BIT);

    //绘制顶点
    render();

    // 鼠标点击事件
    canvas.addEventListener("click", ({ clientX, clientY }) => {
      console.log(clientX, clientY);
      const { left, top, width, height } = canvas.getBoundingClientRect();
      const [cssX, cssY] = [clientX - left, clientY - top];

      //解决坐标原点位置的差异
      const [halfWidth, halfHeight] = [width / 2, height / 2];
      const [xBaseCenter, yBaseCenter] = [
        cssX - halfWidth,
        cssY - halfHeight,
      ];
      // 解决y 方向的差异
      const yBaseCenterTop = -yBaseCenter;
      //解决坐标基底的差异
      const [x, y] = [xBaseCenter / halfWidth, yBaseCenterTop / halfHeight];

      const s = Math.random() * 5 + 2;
      const a = 1;
      const obj = { x, y, s, a };
      stars.push(obj);

      //建立轨道对象
      const track = new Track(obj);
      track.start = new Date();
      track.timeLen = 2000;
      track.loop = true;
      track.keyMap = new Map([
        [
          "a",
          [
            [500, a],
            [1000, 0],
            [1500, a],
          ],
        ],
      ]);
      compose.add(track);

      // render();
    });

    !(function ani() {
      compose.update(new Date());
      render();
      requestAnimationFrame(ani);
    })();

    // 渲染方法
    function render() {
      gl.clear(gl.COLOR_BUFFER_BIT);
      stars.forEach(({ x, y, s, a }) => {
        gl.vertexAttrib2f(a_Position, x, y);
        gl.vertexAttrib1f(a_PointSize, s);
        const arr = new Float32Array([0.87, 0.91, 1, a]);
        gl.uniform4fv(u_FragColor, arr);
        gl.drawArrays(gl.POINTS, 0, 1);
      });
    }
  </script>
</body>

</html>